package practiceProjects.AESandDatabase;

/**
 * @Project ：learn_java
 * @File ：AesIntoDatabase.java
 * @IDE ：IntelliJ IDEA
 * @Author ：自由如风间
 * @Date ：2025/4/29 21:23
 * @Description ：向数据库中存储AES加密的密码和从中读取并解密
 */


import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.sql.*;
import java.util.Base64;

public class AesIntoDatabase {
    // AES 密钥，长度必须为 16、24 或 32 字节
    private static final String AES_KEY = "happyEveryday";
    // 初始化向量，长度必须为 16 字节
    private static final String INIT_VECTOR = "abcdef9876543210";

    // 加密方法
    public static String encrypt(String value) {
        try {
            IvParameterSpec iv = new IvParameterSpec(INIT_VECTOR.getBytes(StandardCharsets.UTF_8));
            SecretKeySpec skeySpec = new SecretKeySpec(AES_KEY.getBytes(StandardCharsets.UTF_8), "AES");

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

            byte[] encrypted = cipher.doFinal(value.getBytes());
            return Base64.getEncoder().encodeToString(encrypted);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    // 解密方法
    public static String decrypt(String encrypted) {
        try {
            IvParameterSpec iv = new IvParameterSpec(INIT_VECTOR.getBytes(StandardCharsets.UTF_8));
            SecretKeySpec skeySpec = new SecretKeySpec(AES_KEY.getBytes(StandardCharsets.UTF_8), "AES");

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);

            byte[] original = cipher.doFinal(Base64.getDecoder().decode(encrypted));
            return new String(original);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    // 连接数据库
    private static Connection connect() {
        String url = "jdbc:sqlite:path/to/your/database.db";
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(url);
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
        return conn;
    }

    // 插入加密数据
    public static void insertData(String site, String userName, String userAccount, String userPassword, String postscript) {
        String sql = "INSERT INTO pswd(site, userName, userAccount, userPassword, postscript) VALUES(?,?,?,?,?)";
        String encryptedPassword = encrypt(userPassword);
        try (Connection conn = connect();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setString(1, site);
            pstmt.setString(2, userName);
            pstmt.setString(3, userAccount);
            pstmt.setString(4, encryptedPassword);
            pstmt.setString(5, postscript);
            pstmt.executeUpdate();
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
    }

    // 查询全部数据并解密
    public static void selectAll() {
        String sql = "SELECT * FROM pswd";
        try (Connection conn = connect();
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery(sql)) {
            while (rs.next()) {
                int id = rs.getInt("id");
                String site = rs.getString("site");
                String userName = rs.getString("userName");
                String userAccount = rs.getString("userAccount");
                String encryptedPassword = rs.getString("userPassword");
                String postscript = rs.getString("postscript");
                String decryptedPassword = decrypt(encryptedPassword);

                System.out.println("ID: " + id);
                System.out.println("Site: " + site);
                System.out.println("User Name: " + userName);
                System.out.println("User Account: " + userAccount);
                System.out.println("Decrypted Password: " + decryptedPassword);
                System.out.println("Postscript: " + postscript);
                System.out.println("---------------------");
            }
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
    }

    public static void main(String[] args) {
        // 插入示例数据
        insertData("example.com", "testUser", "test@example.com", "testPassword", "This is a test");
        // 查询全部数据
        selectAll();
    }
}
